package org.scboy.dbms.service.imp;

import java.util.ArrayList;
import java.util.List;

import org.scboy.coobi.sql.factory.EntityFactory;
import org.scboy.dbms.dao.BaseAppConfigDao;
import org.scboy.dbms.dao.BaseAppDao;
import org.scboy.dbms.dao.BaseAppFileDao;
import org.scboy.dbms.dao.BaseAppPermissionDao;
import org.scboy.dbms.dao.BaseAppServerDao;
import org.scboy.dbms.dao.BaseServersDao;
import org.scboy.dbms.service.BaseAppService;
import org.scboy.utils.entitys.coobi.Model;
import org.scboy.utils.entitys.coobi.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.MD5;

@Service
public class BaseAppServiceImp implements BaseAppService {

	@Autowired
	EntityFactory factory;
	
	@Override
	public Page page(Model params) {
		BaseAppDao dao=factory.getDao(BaseAppDao.class);
		BaseAppServerDao appServerDao=factory.getDao(BaseAppServerDao.class);
		BaseAppFileDao fileDao=factory.getDao(BaseAppFileDao.class);
		params.orderBy("runIndex");
		Page page = dao.page(params);
		for (Model model : page.getData()) {
			model.add("notStart", 0);
			model.add("starting", 0);
			model.add("runing", 0);
			
			if(fileDao.count(Model.create().add("appName", model.getString("appName")))>0) {
				model.add("jarFile", 1);
			}else {
				model.add("jarFile", 0);
			}
			
			//0未启动，1在启动，2已启动
			List<Model> groupDatas= appServerDao.groupByStatus(Model.create().add("appName", model.getString("appName")));
			for (Model gData : groupDatas) {
				switch (gData.getInt("status")) {
				case 0: {
					model.add("notStart",gData.getInt("countNum"));
					break;
				}
				case 1: {
					model.add("starting",gData.getInt("countNum"));
					break;
				}
				case 2: {
					model.add("runing",gData.getInt("countNum"));
					break;
				}
				default:
					break;
				}
			}
		}
		return page;
	}

	@Override
	public boolean add(Model params) {
		BaseAppDao dao=factory.getDao(BaseAppDao.class);
		String appName=params.getString("appName");
		
		//appName不存在
		if(StrUtil.isEmpty(appName)) {
			return false;
		}
		
		//判断appName是否已在数据库
		long count=dao.count(Model.create().add("appName", appName));
		if(count>0) {
			return false;
		}
		
		int result=dao.insert(params);
		if(result>0) {
			return true;
		}else {
			return false;
		}
	}

	@Override
	public boolean delete(String appName) {
		BaseAppDao dao=factory.getDao(BaseAppDao.class);
		BaseAppServerDao serverDao=factory.getDao(BaseAppServerDao.class);
		
		//检查是否有正在启动的服务，获取已经启动的服务
		long count=serverDao.count(Model.create().add("appName", appName).IN("status", new String[] {"1","2"}));
		if(count>0) {
			return false;
		}
		
		//删除微服务部署记录
		serverDao.delete(Model.create().add("appName", appName));
		
		//删除服务器
		int result=dao.delete(Model.create().add("appName", appName));
		if(result>0) {
			return true;
		}else {
			return false;
		}
	}

	@Override
	public boolean update(Model params) {
		BaseAppDao dao=factory.getDao(BaseAppDao.class);
		int result=dao.update(params);
		if(result>0) {
			return true;
		}else {
			return false;
		}
	}

	@Override
	public Model get(String appName) {
		BaseAppDao dao=factory.getDao(BaseAppDao.class);
		return dao.get(Model.create().add("appName", appName));
	}

	@Override
	public List<Model> getAppPaths(String type) {
		BaseAppDao dao=factory.getDao(BaseAppDao.class);
		BaseAppPermissionDao permissinDao=factory.getDao(BaseAppPermissionDao.class);
		List<Model> apps=dao.select(Model.create().orderBy("appName"));
		
		List<Model> result=new ArrayList<Model>();
		for (Model app : apps) {
			app.add("type", "app");
			app.add("label",app.getString("appNote"));
			app.add("value","");
			
			Model params=Model.create().add("appName", app.getString("appName")).orderBy("persmissionName");
			if("submit".equals(type)) {
				params.IN("httpMethod", new String[] {"PUT","POST","ALL"});
			}
			List<Model> permissin= permissinDao.select(params);
			for (Model perm : permissin) {
				app.add("type", "permissin");
				perm.add("label",perm.getString("persmissionName"));
				perm.add("value","/"+perm.getString("appName")+perm.getString("persmissionuUrl"));
			}
			if(permissin.size()>0) {
				app.add("children", permissin);
				result.add(app);
			}
		}
		return result;
	}

	@Override
	public List<Model> list() {
		BaseAppDao dao=factory.getDao(BaseAppDao.class);
		return dao.select(Model.create().orderBy("runIndex"));
	}

	@Override
	public void register(String ip, int port, String appName, String deploymentPath,String config,String docType) {

		BaseAppDao appDao=factory.getDao(BaseAppDao.class);
		BaseAppServerDao appServerDao=factory.getDao(BaseAppServerDao.class);
		BaseServersDao serverDao=factory.getDao(BaseServersDao.class);
		BaseAppConfigDao configDao=factory.getDao(BaseAppConfigDao.class);
		
		
		//检查微服务是否存在
		if(appDao.count(Model.create().add("appName", appName))==0) {
			Integer maxIndex=appDao.max(new String[]{"runIndex"}, Model.create().NE("appName", "gateway-server")).getInt("runIndex");
			if(maxIndex==null) {
				maxIndex=0;
			}else {
				maxIndex=maxIndex+1;
			}
			Model app=Model.create();
			app.add("appName", appName);
			app.add("runIndex", maxIndex);
			app.add("appType", 1);
			appDao.insert(app);
		}
		
		//检查微服务配置
		if(configDao.count(Model.create().add("appName", appName))==0) {
			Model appConfig=Model.create();
			appConfig.add("id", UUID.randomUUID().toString());
			appConfig.add("appName", appName);
			appConfig.add("configName", "默认配置");
			appConfig.add("configValue", config);
			appConfig.add("docType", docType);
			appConfig.add("activity", 1);
			configDao.insert(appConfig);
		}
		
		//检查服务器是否存在
		if(serverDao.count(Model.create().add("ip", ip))==0) {
			Model server=Model.create();
			server.add("ip", ip);
			server.add("serverPath", deploymentPath);
			server.add("serverState", 1);
			serverDao.insert(server);
		}
		
		String serverId=MD5.create().digestHex(appName+"_"+ip+":"+port);
		
		//检查微服务部署是否存在
		if(appServerDao.count(Model.create().add("id", serverId))==0) {
			appServerDao.insert(
					Model.create()
					.add("id", serverId)
					.add("appName", appName)
					.add("ip", ip)
					.add("port", port)
					.add("serverMsg", "")
					.add("deploymentPath", deploymentPath)
					.add("status", 1));
		}else {
			appServerDao.update(
					Model.create().add("id", serverId)
					.add("deploymentPath", deploymentPath)
					.add("serverMsg", "")
					.add("status", 1));
		}
	}

	@Override
	public boolean upload(String appName,byte[] binary) {
		BaseAppFileDao appDao=factory.getDao(BaseAppFileDao.class);
		int count=0;
		if(appDao.count(Model.create().add("appName", appName))>0) {
			count=appDao.update(Model.create().add("appName", appName).add("appBinary", binary));
		}else {
			count=appDao.insert(Model.create().add("appName", appName).add("appBinary", binary));
		}
		if(count>0) {
			return true;
		}else {
			return false;
		}
	}

}
